using BepuUtilities;

namespace BepuPhysics
{
    /// <summary>
    /// 按以下顺序更新模拟：枕木->集成速度和更新实体边界框->碰撞检测->解算器->集成实体姿势->数据结构优化。
    /// </summary>
    public class PositionLastTimestepper : ITimestepper
    {
        /// <summary>
        /// 在休眠程序完成之后、身体集成之前激发。
        /// </summary>
        public event TimestepperStageHandler Slept;
        /// <summary>
        /// 在更新了物体的速度和边界框之后,但在开始碰撞检测之前。
        /// </summary>
        public event TimestepperStageHandler BeforeCollisionDetection;
        /// <summary>
        /// 在识别所有碰撞之后、但在解决约束之前激发。
        /// </summary>
        public event TimestepperStageHandler CollisionsDetected;
        /// <summary>
        /// 在解算器执行之后、身体姿势集成之前激发。
        /// </summary>
        public event TimestepperStageHandler ConstraintsSolved;
        /// <summary>
        /// 在实体集成其姿势之后,在增量优化数据结构之前激发。
        /// </summary>
        public event TimestepperStageHandler PosesIntegrated;

        public void Timestep(Simulation simulation, float dt, IThreadDispatcher threadDispatcher = null)
        {
            simulation.Sleep(threadDispatcher);
            Slept?.Invoke(dt, threadDispatcher);

            simulation.IntegrateVelocitiesBoundsAndInertias(dt, threadDispatcher);
            BeforeCollisionDetection?.Invoke(dt, threadDispatcher);

            simulation.CollisionDetection(dt, threadDispatcher);
            CollisionsDetected?.Invoke(dt, threadDispatcher);

            simulation.Solve(dt, threadDispatcher);
            ConstraintsSolved?.Invoke(dt, threadDispatcher);

            simulation.IntegratePoses(dt, threadDispatcher);
            PosesIntegrated?.Invoke(dt, threadDispatcher);

            simulation.IncrementallyOptimizeDataStructures(threadDispatcher);
        }
    }
}
